import TruffleContract from 'truffle-contract'
// import DB from '../../build/contracts/DB.json'
// import MarketPlaceContract from '../../build/contracts/MarketPlace.json'
import BaseMatchContract from '../../build/contracts/BaseMatch.json'
import { API, CONTRACT } from '../util/constants'

let blockchainManager = null

class BlockchainManager {

  constructor () {
    blockchainManager = blockchainManager || this
    return blockchainManager
  }

  // 新增
  activeContract;

  horseContract;
  matchContract;
  hasInit = false;
  initContract (state) {
    // this.horseContract = TruffleContract(MarketPlaceContract)
    // this.horseContract.setProvider(state.web3.instance().currentProvider)
    // this.horseContract.deployed()
    // .then((contractInstance) => {
    //   console.log('赛马合约 创建成功')
    // })
    // .catch((error) => {
    //   console.log('赛马合约 创建失败 (' + error + ')')
    // })
    console.log('init blockchainmanager')
    this.matchContract = TruffleContract(BaseMatchContract)
    this.matchContract.setProvider(state.web3.instance().currentProvider)
    this.matchContract.deployed()
      .then((contractInstance) => {
        console.log('比赛合约 创建成功')
        this.hasInit = true
      })
      .catch((error) => {
        console.log('比赛合约 创建失败 (' + error + ')')
      })
  }

  // INPUT
  // state
  // message.params
  // message.methodName
  // message.methodType
  // message.event
  // OUTPUT
  // .data
  // ERROR
  // .error
  // .message
  accessContract (state, contractName, message = {}, isProtected = false) {
    // const state = dataObject.state
    return new Promise((resolve, reject) => {
      console.log(`state ${state}, web3 = ${state.web3}, instance = ${state.web3.instance}`)

      if (!state || !state.web3 || !(state.web3.instance)) {
        reject({ error: true, warningMessage: 'Web3 is not initialised. Use a Web3 injector' })
      } else {
        state.web3.instance().eth.getAccounts((error, accounts) => {
          if (error) {
            reject({ error, message: 'Unable to get coinbase for this operation' })
          } else {
            this.dispatchContract(contractName, accounts, message, isProtected, resolve, reject)
          }
        })
      }
    })
  }

  // 接口分发
  dispatchContract (contractName, accounts, message, isProtected, resolve, reject) {
    if (contractName === CONTRACT.HORSE) {
      this.activeContract = this.horseContract
    } else if (contractName === CONTRACT.MATCH) {
      this.activeContract = this.matchContract
    } else {
      // 断言
    }

    var theAccount = accounts[0]
    console.log(message.methodName + ' invoking')
    if (message.methodName === API.GET_ACCOUNTS) {
      console.log(API.GET_ACCOUNTS + ' incoked')

      resolve(theAccount)
    } else {
      console.log(message.methodName + ' incoked')

      // 组装参数
      var param = null

      if (isProtected) {
        param = [].concat(...[theAccount, message.params])
      } else {
        param = [].concat(...[message.params])
      }

      // 过滤掉 null
      param = param.filter(_ => !!_)

      console.log('input param = ' + JSON.stringify(param))

      // 调用合约
      if (message.methodType === 'GET') {
        this.activeContract.deployed()
        .then((contractInstance) => {
          contractInstance[message.methodName]['call'](...param, {from: theAccount})
          .then((result) => {
            // Successful Fetch

            console.log('[GET] result = ' + JSON.stringify(result))

            resolve(result)
          })
          .catch((error) => {
            reject(error)
          })
        })
        .catch((error) => {
          reject({ error, isValid: true, warningMessage: "We couldn't find Eth-Vue Smart Contracts on your detected network. This is because the Smart Contracts aren't deployed there." })
        })
      } else if (message.methodType === 'POST') {
        this.activeContract.deployed()
        .then((contractInstance) => {
          contractInstance[message.methodName](...param, {from: theAccount, value: message.amount})
          .then((result) => {
            // Successful Fetch
            var filtered = result['logs'].filter(_ => _.event === message.event)

            console.log('[POST] result = ' + JSON.stringify(result))

            if (filtered.length > 0) {
              resolve(filtered.map(_ => {
                return _['args']
              }))

              // console.log('[POST] logs[0] = ' + JSON.stringify(filtered[0]))
            } else {
              resolve({})
            }
          })
          .catch((error) => {
            reject(error)
          })
        })
        .catch((error) => {
          reject({ error, isValid: true, warningMessage: "We couldn't find Eth-Vue Smart Contracts on your detected network. This is because the Smart Contracts aren't deployed there." })
        })
      }
    }
  }

}

blockchainManager = new BlockchainManager()
export default blockchainManager
